package baidu.bms.filter;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.rpc.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author sunqiyuan
 * @Classname DemoFilter
 * @Description TODO
 * @Date 2020/10/15 11:05 上午
 * @Version V1.0
 */
// 无论consumer 和 provider 统一激活
@Activate(group = {"provider", "consumer"})
public class DemoFilter implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(DemoFilter.class);
    private static String[] transparentHeaders = {"traceId"};

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Map<String, String> attachments = invocation.getAttachments();
        if (attachments.get("traceId") == null) {
            attachments.put("traceId", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        }
        try {
            Map<String, String> context = DubboContext.getContextMap();

            if (context == null) {
                // server端，第一次接收数据
                context = new HashMap<>();
                for (String header : transparentHeaders) {
                    String value = attachments.get(header);
                    if (value != null) {
                        context.put(header, value);
                    }
                }
                DubboContext.setContextMap(context);
                System.out.println("hello DemoFilter in server!" + invocation.getAttachments());
            } else {
                // client 端
                attachments.putAll(context);
                DubboContext.setContextMap(null);
                System.out.println("hello DemoFilter in client !" + invocation.getAttachments());
            }


        } catch (Throwable t) {
            logger.warn("Exception in DemoFilter (" + invoker + ") when add attachments", t);
        }
        return invoker.invoke(invocation);

    }
}
